/**
 * Copyright (c) 2009 blurredVision
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
 * associated documentation files (the "Software"), to deal in the Software without restriction, 
 * including without limitation the rights to use, copy, modify, merge, publish, distribute, 
 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is 
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all copies or 
 * substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT 
 * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT 
 * OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
#ifndef __MODEL_IMODELBASE_H__
#define __MODEL_IMODELBASE_H__

#pragma once

#include "IResource.h"
#include "sg/SceneNode.h"
#include "IModelKFAnimated.h"
#include "IModelBaseRenderer.h"
#include "IMesh.h"

#include <string>
#include <map>
#include <list>

namespace model {

enum eModelType {
	MODEL_BASE = 0,
	MODEL_STATIC,
	MODEL_KEYFRAME
};

/// Model header. Stores information about a model
struct sModelHeader {
	char         version[3];		///< A 3 byte identifier for the format
	eModelType   modelType;			///< The type of the model: Static, Dynamic, Bones animated model
	unsigned int numMeshes;
};

/// Mesh data header. Stores information about a mesh
struct sMeshDataHeader {
	unsigned int numVertices;		///< The number of vertices of the model
	unsigned int numNormals;		///< The number of normals of the model
	unsigned int numBinormals;		///< The number of binormals of the models
	unsigned int numTangents;		///< The number of tangents of the model
	unsigned int numTexCoords;		///< The number of texture coordinates of the model
	unsigned int numFaces;			///< The number of faces in the model
};

/**
 * \ingroup CoreEngine
 *
 * The IModelBase interface.<br>
 * Container format for static and keyframe models.<br>
 * A model is stored in a custom binary format.<br>
 *
 * \date 04-04-2007
 *
 * \author juckel
 *
 */
class DLL_EXPORT IModelBase :
	public sg::SceneNode,
	public IModelKFAnimated
{
public:
	/// Static method to load an model from a file
	static IModelBase* Load(const std::string &filename);

	/// Update the model
	virtual void update(double dt);

	/// Return the type of the model
	eModelType getModelType() const;

	/// Return a certain mesh given its name
	IMesh* getMeshByName(const std::string &name);

	/// Return a certain mesh by its ID
	IMesh* getMesh(unsigned int num);

	/// Return the number of meshes
	unsigned int getNumMeshes() const;

	virtual SceneNode* rawcopy();

	typedef std::map<std::string, IMesh*> mesh_list;
	const mesh_list* getMesh_List_BoundingVols();

protected:
	IModelBase(const eModelType& type);
	virtual ~IModelBase(void);

	void initMaterial(sComplexMaterial* material);

	/// Load the mesh data from the file
	bool loadMeshes(FILE *file) ;

	/// Load the data corresponding to the type of the model
	virtual bool loadData(FILE* file);

	unsigned int                  m_uiNumMeshes;	///< The number of meshes in the model
	
	mesh_list m_lMeshes;		///< A map that stores all the meshes
	
	mesh_list m_lBoundingVols;
	eModelType                    m_modelType;		///< The type of the model
};

} // namespace

#endif
